PostgreSQL 安全管理 数据脱敏 Anonymizer 默认策略脱敏(Privacy By Default)

1 背景知识

1.1 指导原则

GDPR 原则引入了默认数据保护的概念

简单来说,在默认情况下,应该确保使用最高的隐私保护标准处理数据。

根据这一原则,表上所有的列都应该被脱敏,而无需为每个表声明规则,并应用默认的脱敏规则。

要启用此功能需要将选项 anon.privacy_by_default 设置为 on

1.2 默认脱敏支持的数据类型

支持默认脱敏规则的数据类型如下:

varchar,char,text,timestamp, timestamptz,date,time,timetz,integer,smallint,tinyint,bigint,smallserial,serial, bigserial,boolean,real,double

1.3 默认脱敏的规则

数据类型 默认的脱敏规则
字符串类型 空值
数字类型 0(不保证精度)
布尔类型 f
时间类型 年月日部分:1970-01-01, 时分秒部分: 00:00 :00

2 如何使用默认隐私保护

2.1 准备一张 acccess_log

表中包含 HTTP 日志。

CREATE TABLE public.access_logs (date_open timestamp,
						  ip_addr varchar(16),
						  url varchar(255),
						  browser_agent varchar(255)
						  );
INSERT INTO access_logs values('2009-01-08 00:00:00','192.168.100.128','/home.html','Mozilla/5.0 (Windows; en_US)');
SELECT * FROM access_logs LIMIT 1;
//屏幕输出:
      date_open      |     ip_addr     |    url     |        browser_agent
---------------------+-----------------+------------+------------------------------
 2009-01-08 00:00:00 | 192.168.100.128 | /home.html | Mozilla/5.0 (Windows; en_US)
(1 row)

2.2 激活默认的隐私保护

ALTER DATABASE postgres SET anon.privacy_by_default = True;

此参数将会在未来的会话生效,现在将会对表进行脱敏处理,而无需编写任何编写任何规则。

SELECT anon.anonymize_table('access_logs');
 anonymize_database
--------------------
 t
SELECT * FROM access_logs LIMIT 1;
 date_open | ip_addr | url | browser_agent
-----------+---------+-----+---------------
           |         |     | unkown

3 指定非脱敏的字段

从上面可知,当使用 anon.privacy_by_default 时,所有的列都会被替换为空值,这个数据将会被破坏。

那如何指定某个字段不进行脱敏。

例如,我们想要保留 url 字段的真实值。

SECURITY LABEL FOR anon ON COLUMN access_logs.url
IS 'NOT MASKED';

也可以通过脱敏规则 来实现,下面规则将会替换数值。

SECURITY LABEL FOR anon ON COLUMN access_logs.url
IS 'MASKED WITH VALUE url';

下面是对 data_open 字段的脱敏并对日期进行泛化,只保留年份。

SECURITY LABEL FOR anon ON COLUMN access_logs.date_open
IS 'MASKED WITH FUNCTION make_date(EXTRACT(year FROM date_open)::INT,1,1)';

4 使用默认脱敏保护时的注意事项

现在在 data_open 字段加一个非空约束:

ALTER TABLE public.access_logs
  ALTER COLUMN date_open
  SET NOT NULL;

现在对这张表进行脱敏处理,将会出现违反约束的情况。

SELECT anon.anonymize_table('public.access_logs') as test4;
ERROR:  Cannot mask a "NOT NULL" column with a NULL value
HINT:  If privacy_by_design is enabled, add a default value to the column

解决方案是定一个默认值即可。

ALTER TABLE public.access_logs
  ALTER COLUMN date_open
  SET DEFAULT now();
Note

其他约束(外键、UNIQUE、CHEK等)在没有 DEFATULT 值下也可以正常工作。